package com.dbpediamobile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Layout;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class BusquedaSimple<setOnItemClickListener> extends Activity {
	public EditText txtFiltro;
	public static AutoCompleteTextView autocInput;
	private boolean isVisible = false, pagSgt = true;;
	private TextView tvFiltro, texto, txtPag;
	private ImageButton botonBuscar, botonCerrar;
	private LinearLayout layoutFiltro;
	private int pagina=0;
	private float downXValue;
	private String[] items;
	/* variable para guardar la entrada de texto*/
	public static String input=""; 
	/* lista de sugerencias */
	private ArrayAdapter<String> adapter;
	/* lista para almacenar los resultados */
	private ArrayList<BusquedaResult> listaResultados = new ArrayList();
	/* lista para almacenar los resultados luego de filtrados */
	private ArrayList<BusquedaResult> listaResultFiltro = new ArrayList();
	/* lista auxiliar para almacenar los resultados */
	private ArrayList<BusquedaResult> listaAux = new ArrayList();
	/* variable de barra de carga */
	private ProgressDialog progressD = null; 
	
	/* manejador del hilo, segun el tipo del mensaje */
	Handler handler = new Handler(){
		public void handleMessage(Message msg) {
	         if(msg.what==1){
	        	 setContentView(R.layout.busquedasimple);
	             /* se declaran items */
	        	 autocInput = (AutoCompleteTextView)findViewById(R.id.bs_autocomplete);	
	        	 txtPag = (TextView)findViewById(R.id.npag);
	        	 texto = (TextView)findViewById(R.id.std_salida3);
	        	 texto.setOnTouchListener(mover);
	           	 tvFiltro = (TextView)findViewById(R.id.bs_filtro_txt);
	           	 txtFiltro = (EditText)findViewById(R.id.bs_input_filtro);
	           	 botonCerrar = (ImageButton)findViewById(R.id.button_cerrarfiltro);
	        	 botonCerrar.setOnClickListener(cerrar);
	           	 /* se realiza la busqueda */
	        	 cargar(1);
	        	 /* se oculta por defecto los item de filtro */
	        	 layoutFiltro = (LinearLayout)findViewById(R.id.bs_layoutfiltro);
	        	 layoutFiltro.removeAllViews();    	 
	             /* se declara eventos e items de busqueda simple */
	             botonBuscar = (ImageButton)findViewById(R.id.button_busq_simple2);
	             botonBuscar.setOnClickListener(busqueda);
	         }
	         if(msg.what==2){
	        	 cargar(2);
	         }
	         /* finaliza barra de carga */
	         progressD.dismiss();
	   }
	};
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /* se despliega barra de carga, mientras se cargan los datos */
        progressD = ProgressDialog.show(this,       
                "Please wait...", "Loading...", true);
        /* se crea un hilo para ejecutar el proceso */
        new Thread(new Runnable(){
            public void run(){      	
            	/* espera 100ms entre cada update */
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {e.printStackTrace();}
				/* se envia el mensaje al manejador que ejecuta las UI */
            	handler.sendEmptyMessage(1);
           }
        }).start();
	}	
	
	/* realiza una busqueda simple
	 * tipos de ejecucion: 1=inicio, 2=boton */
	private void cargar(int tipo){
		listaResultados.clear();
		String input="";
		/* dependiendo del tipo, se da un valor al input */
		if(tipo==1){
			DBPediaMobile dbp = new DBPediaMobile();
			input = dbp.txtInput.getText().toString().trim();
		}
		if(tipo==2){
			input = autocInput.getText().toString();
		}
		/* limpia y formatea espacios del input*/
		if(input.contains(" ")){
			input=input.replace(" ", "+AND+");
		}
		autocInput.setText(input.replace("+AND+", " "));
        String query = consultarTexto1(input);
    	/* intenta obtener la consulta*/
        try {
    		ConexionBusqueda c = new ConexionBusqueda();
    		ArrayList <BusquedaResult> resultados = new ArrayList();
        	resultados = c.conectar(query,1);
        	String out = "";
        	/* items de sugerencia */
        	items =  new String[resultados.size()];
        	for(int i=0;i<resultados.size();i++){
        		BusquedaResult br = new BusquedaResult();
        		/* si es muy largo la url, se acorta */
        		if(resultados.get(i).url.length()<60){
        			out += resultados.get(i).nombre+"\n"+resultados.get(i).url.replace("http://dbpedia.org/resource/","DBPedia:")+" \n\n";
        			//br.url = resultados.get(i).url.replace("http://dbpedia.org/resource/","");
        		}
        		else{
        			out += resultados.get(i).nombre+"\n"+"DBPedia: ... (espacio insuficiente)"+" \n\n";
        			//br.url = "DBPedia: ... (espacio insuficiente)";
        		}
        		br.url= resultados.get(i).url.replace("http://dbpedia.org/resource/","");
         		items[i] = new String(resultados.get(i).nombre);
        		br.nombre = resultados.get(i).nombre;
				listaResultados.add(br);
        	}
        	/* en caso de que no hayan mas url que mostrar */
        	if(out.trim().equals("")){
        		pagSgt=false;
        		out="No hay mas resultados\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n...";
        	}
        	texto.setText(out);
        	/* se agregan sugerencias */
        	adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, items);
        	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            autocInput.setAdapter(adapter);
		} catch (IOException e) {
		}
	}
	
	/* genera consulta de texto simple */
    private String consultarTexto1(String input){
    	String input2=input.replace("+AND+", "'%2C'");
    
    	String query = "++++select+%0D%0A%09%09++%09(<sql:s_sum_page>+(<sql:vector_agg>+" +
		"(<bif:vector>+(%3Fc1,+%3Fsm)),+<bif:vector>+('"+input2+"')))++as+%3Fres+where" +
		"+{+{+%0D%0A++++++select+(<SHORT_OR_LONG::>(%3Fs1))+as+%3Fc1,++(<sql:S_SUM>" +
		"+(+<SHORT_OR_LONG::IRI_RANK>+(%3Fs1),+<SHORT_OR_LONG::>(%3Fs1textp),+" +
		"<SHORT_OR_LONG::>(%3Fo1),+%3Fsc+)+)+as+%3Fsm++where+{+%3Fs1+" +
		"%3Chttp://dbpedia.org/ontology/abstract%3E+" +
		"+%3Fo1+.+%3Fo1+bif:contains++'("+input+")'++option+(sc" +
		"ore+%3Fsc)++.+}order+by+desc+(<sql:sum_rank>+((<sql:S_SUM>+(+<SHORT_OR_LO" +
		"NG::IRI_RANK>+(%3Fs1),+<SHORT_OR_LONG::>(%3Fs1textp),+<SHORT_OR_L" +
		"ONG::>(%3Fo1),+%3Fsc+)+)+)+)+limit+20++offset+"+pagina+"}}";
    	
    	
    	return query;
    }
 
    /* oyente para el boton de busqueda simple */
    private OnClickListener busqueda = new OnClickListener() {
        public void onClick(View v) {
        	pagina=0;
        	pagSgt=true;
        	mostrarProgress();
        	txtPag.setText("Page number: "+(pagina/20+1));
        }
    };

    /* oyente para el input filtrar (AVANZADO, 1)
     * entrega todos los resultados por cada palabra */
    private OnKeyListener filtrar1 = new OnKeyListener() {
        public boolean onKey(View v, int  keycode, KeyEvent keyevent) {
            TextView texto = (TextView)findViewById(R.id.std_salida3);
			String out = "", keyWord=txtFiltro.getText().toString().trim().toLowerCase();
			listaResultFiltro.clear();
			/* input filtro vacio */
			if(keyWord.equals("")){
				out=listarResultados();
			}
			/* input filtro con contenido */
			else{
				/* solo contiene una palabra el input filtro */
				if(!keyWord.contains(" ")){
					for(int i=0;i<listaResultados.size();i++){
						String word=listaResultados.get(i).nombre.toLowerCase();
						if(word.contains(keyWord)){
							BusquedaResult br = new BusquedaResult();
							br.nombre=listaResultados.get(i).nombre;
							br.url=listaResultados.get(i).url;
							listaResultFiltro.add(br);
							out += listaResultados.get(i).nombre+"\n"+listaResultados.get(i).url+" \n\n";
						}
					}
				}
				/* contiene mas de una palabra el input filtro */
				else{
					listaAux.clear();
					int e=0;
					while(true){
						int posWord = keyWord.indexOf(" ",e);
						if(posWord==-1){
							posWord=keyWord.length();
						}
						String subKeyWord = keyWord.substring(e, posWord); 
						for(int i=0;i<listaResultados.size();i++){
							String word=listaResultados.get(i).nombre.toLowerCase();
							if(word.contains(subKeyWord) && !listaAux.contains(listaResultados.get(i))){
								listaAux.add(listaResultados.get(i));
								BusquedaResult br = new BusquedaResult();
								br.nombre=listaResultados.get(i).nombre;
								br.url=listaResultados.get(i).url;
								listaResultFiltro.add(br);
								out += listaResultados.get(i).nombre+"\n"+listaResultados.get(i).url+" \n\n";
							}
						}
						if(posWord==keyWord.length()){
							break;
						}
						else{
							e=posWord+1;
						}
					}
				}
			}
			texto.setText(out);
			return false;
        }
    };
    
    /* oyente para el input filtrar (SIMPLE, 2)
     * entrega los resultados de la frase o palabra */
    private OnKeyListener filtrar2 = new OnKeyListener() {
        public boolean onKey(View v, int  keycode, KeyEvent keyevent) {
            TextView texto = (TextView)findViewById(R.id.std_salida3);
			String out = "", keyWord=txtFiltro.getText().toString().trim().toLowerCase();
			listaResultFiltro.clear();
			/* input filtro vacio */
			if(keyWord.equals("")){
				out=listarResultados();
			}
			/* input filtro con contenido */
			else{
				for(int i=0;i<listaResultados.size();i++){
					String word=listaResultados.get(i).nombre.toLowerCase();
					if(word.contains(keyWord)){
						BusquedaResult br = new BusquedaResult();
						br.nombre=listaResultados.get(i).nombre;
						br.url=listaResultados.get(i).url;
						listaResultFiltro.add(br);
						out += listaResultados.get(i).nombre+"\n"+listaResultados.get(i).url+" \n\n";
					}
				}
			}
			texto.setText(out);
			return false;
        }
    };
    
    /* cierra el filtro */
    private OnClickListener cerrar = new OnClickListener() {
        public void onClick(View v) {
        	txtFiltro.setText("");
        	TextView texto = (TextView)findViewById(R.id.std_salida3);
        	String out=listarResultados();
        	texto.setText(out);
        	layoutFiltro.removeAllViews();
        	isVisible=false;
        }
    };
    
    /* manejador del seleccionador en menu */
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	case R.id.bs_goback:
    		Intent intent = new Intent(BusquedaSimple.this, DBPediaMobile.class);
    		startActivity(intent); 
    		break;
    	/* filtro avanzado */
        case R.id.bs_filtro1:
        	/* si el filtro no es visible, se muestra */
        	if(isVisible==false){
        		txtFiltro.setWidth(170);
        		layoutFiltro.addView(tvFiltro);
        		layoutFiltro.addView(txtFiltro);
        		layoutFiltro.addView(botonCerrar);
        		
        		isVisible=true;
        	}
        	txtFiltro.setWidth(170);
        	tvFiltro.setText("Filtro Avanzado");
        	txtFiltro.setOnKeyListener(filtrar1);
        	
        	break;
        /* filtro simple */
        case R.id.bs_filtro2:
        	/* si el filtro no es visible, se muestra */
        	if(isVisible==false){
        		txtFiltro.setWidth(185);
        		layoutFiltro.addView(tvFiltro);
        		layoutFiltro.addView(txtFiltro);
        		layoutFiltro.addView(botonCerrar);
        		
        		isVisible=true;
        	}
        	txtFiltro.setWidth(185);
        	tvFiltro.setText("Filtro Simple");
        	txtFiltro.setOnKeyListener(filtrar2);
        	
        	break;
        /* pagina siguiente de resultados */
    	case R.id.bs_siguiente:
    		txtFiltro.setText("");
    		pagina=pagina+20;
    		mostrarProgress();
    		break;
    	/* pagina anterior de resultados */
    	case R.id.bs_anterior:
    		if(pagina!=0){
    			txtFiltro.setText("");
    			pagina=pagina-20;
    			mostrarProgress();
    		}
    		break;
    	/* vision de grafo */
    	case R.id.menu_ir_grafo:
    		intent = new Intent(BusquedaSimple.this, Grafo.class);
    		startActivity(intent); 
    		break;
    	}
    	txtPag.setText("Page number: "+(pagina/20+1));
        return false;
    }

    /* agrega los menus directamente desde bs_menu.xml */
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.bs_menu, menu);
        return true;
    }
    
    /* navegador touch */
    private OnTouchListener mover = new OnTouchListener() {
    	public boolean onTouch(View arg0, MotionEvent arg1) {
    		switch (arg1.getAction()){
            case MotionEvent.ACTION_DOWN:
                /* guarda X cuando se hace DOWN */
            	downXValue = arg1.getX();
                break;
            case MotionEvent.ACTION_UP:
                /* obitene X cuando se hace UP */
                float currentX = arg1.getX();            
                /* touch movimiento, cambia pagina */
                if(downXValue < currentX || downXValue > currentX){
                	/* vuelve a la pagina anterior */
                	if(downXValue < currentX){
                		txtFiltro.setText("");
                		if(pagina!=0){
                			pagSgt=true;
                			pagina=pagina-20;
                			mostrarProgress();
                		}
                	}
                	/* va a la pagina siguiente */
                	if(downXValue > currentX){
                		if(pagSgt==true){
                			txtFiltro.setText("");
                			pagina=pagina+20;
                			mostrarProgress();
                		}
                	}
                	txtPag.setText("Page number: "+(pagina/20+1));
                }
                else{
                	/* touch click, entra a pagina */
                	for(int i=0;true;i++){
                		if(48.5*i>arg1.getY()){
                			if(arg1.getY()>(48.5*(i-1))+28.5){
                				/* posicion en blanco */
                				break;
                			}
                			else{
                				/* se entra a pagina */
                				if(isVisible==false){
                					input = listaResultados.get(i-1).url.replace(" ", "_");
                					//Toast.makeText(getApplicationContext(), "R: "+input, Toast.LENGTH_SHORT).show();
                					Intent intent = new Intent(BusquedaSimple.this, ArticuloSimple.class);
                			        startActivity(intent); 
                				}
                				else{
                					input = listaResultFiltro.get(i-1).url.replace(" ", "_");
                					//Toast.makeText(getApplicationContext(), "R: "+input, Toast.LENGTH_SHORT).show();
                					Intent intent = new Intent(BusquedaSimple.this, ArticuloSimple.class);
                			        startActivity(intent); 
                				}
                				break;
                			}
                		}
                	}
                }
                break;
    		}
    		return true;
        }
    };
    
    private String listarResultados(){
    	String out="";
    	listaResultFiltro.clear();
    	for(int i=0;i<listaResultados.size();i++){
    		BusquedaResult br = new BusquedaResult();
			br.nombre=listaResultados.get(i).nombre;
			br.url=listaResultados.get(i).url;
			listaResultFiltro.add(br);
			out += listaResultados.get(i).nombre+"\n"+listaResultados.get(i).url+" \n\n";
		}
    	return out;
    }
    
    /* muestra progeso de carga */
    private void mostrarProgress (){
    	/* se despliega barra de carga, mientras se cargan los datos */
    	progressD = ProgressDialog.show(BusquedaSimple.this,       
                "Please wait...", "Loading...", true);
    	/* se crea un hilo para ejecutar el proceso */
        new Thread(new Runnable(){
            public void run(){      	
            	/* espera 100ms entre cada update */
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {e.printStackTrace();}
				/* se envia el mensaje al manejador que ejecuta las UI */
            	handler.sendEmptyMessage(2);
	        }
        }).start();
    }
}
